﻿using Interface_ManTuLuoBA.DBC;
using Interface_ManTuLuoBA.Tools;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.Validation;
using System.Linq;
using System.Web.Services;
using System.Xml;

namespace Interface_ManTuLuoBA.Controllers
{
    //TODO HIS KSCODE表，添加dh_code和dh_name，形成对照，最终依然使用我方code，name作为传入参数
    public class WebService_ManTuLuoBA : System.Web.Services.WebService
    {
        //日志错误信息分隔符
        private readonly String LogLine = "\r\n\r\n";

        //数据库联接
        private DB db = new DB();

        //日志打印工具
        private log4net.ILog log = log4net.LogManager.GetLogger("红会医院接口:");

        /// <summary>
        /// 测试方法
        /// </summary>
        /// <param name="hi"></param>
        /// <returns></returns>
        [WebMethod(Description = "测试：单元测试 1.入院 5.取消入院 4.出院 3.取消出院 2.转科 6.病案")]
        public string A_Test_Inner(int hi)
        {

            String TempStr;
            switch (hi)
            {
                case 1:
                    //InHosp
                    TempStr = MyTools.ReadPathStr(@"D:\GitHub\Interface_ManTuLuoBA\Interface_ManTuLuoBA\Assets\HIS_InHosp1.xml");
                    return InHosp(TempStr);

                case 5:
                    //CancleInHosp
                    TempStr = MyTools.ReadPathStr(@"C:\Users\norma\OneDrive\代码库\Interface_ManTuLuoBA\Interface_ManTuLuoBA\Assets\HIS_InHosp5.xml");
                    return CancelInHosp(TempStr);

                case 4:
                    //OutHosp
                    TempStr = MyTools.ReadPathStr(@"C:\Users\norma\OneDrive\代码库\Interface_ManTuLuoBA\Interface_ManTuLuoBA\Assets\HIS_InHosp4.xml");
                    return OutHosp(TempStr);

                case 3:
                    //CancleOutHosp
                    TempStr = MyTools.ReadPathStr(@"C:\Users\norma\OneDrive\代码库\Interface_ManTuLuoBA\Interface_ManTuLuoBA\Assets\HIS_InHosp3.xml");
                    return CancelOutHosp(TempStr);

                case 2:
                    //ChangeKS
                    TempStr = MyTools.ReadPathStr(@"C:\Users\norma\OneDrive\代码库\Interface_ManTuLuoBA\Interface_ManTuLuoBA\Assets\HIS_InHosp2.xml");
                    return ChangeKS(TempStr);

                case 6:
                    TempStr = MyTools.ReadPathStr(@"D:\GitHub\Interface_ManTuLuoBA\Interface_ManTuLuoBA\Assets\MTLXml.xml");
                    return SetBAXml(TempStr);

                default:
                    return hi.ToString();
            }
        }

        /***以下为，接口方法*********************************************************************************************************/

        /// <summary>
        /// 连接测试
        /// </summary>
        /// <returns></returns>
        [WebMethod(Description = "测试：Http连接")]
        public string A_Test_Connect()
        {
            log.Info("测试连接，测试成功");
            return "Connect successful!";
        }

        /// <summary>
        /// 病案首页数据
        /// </summary>
        /// <param name="xml"></param>
        /// <returns></returns>
        [WebMethod(Description = "对曼荼罗:病案首页数据")]
        public string SetBAXml(String xml)
        {
            log.Info(LogLine + "设置病案信息");

            //操作编码，插入临时表需要的唯一编码
            int UserIDTemp = db.GetUniqueNo();

            log.Info("插入临时表需要的唯一编码:" + UserIDTemp.ToString());

            #region>>解析数据/数据校验
            //错误信息list
            List<Err> errs = new List<Err>();
            //XML解析工具
            XmlDocument xmlDoc = new XmlDocument();
            //XML数据容器 用于放置数据实体对象
            BA_FPage fpage = new BA_FPage();
            List<C_BA_Operation> operations = new List<C_BA_Operation>();
            List<C_BA_Diagnose> diagnoses = new List<C_BA_Diagnose>();
            List<BA_Invoice> invoices = new List<BA_Invoice>();
            //解析XML1
            try
            {
                /*可能产生找不到指定节点的异常*/
                #region--获取根节点 定义子节点对象
                xmlDoc.LoadXml(xml);
                XmlNode root = xmlDoc.DocumentElement;
                XmlNode DataContext = root.SelectSingleNode("DataContext");
                XmlNode BA_Fpage_Node = DataContext.SelectSingleNode("BA_Fpage");
                XmlNodeList BA_CastList = DataContext.SelectNodes("BA_Cost");
                XmlNodeList BA_OperationList = DataContext.SelectNodes("BA_Operation");
                XmlNodeList BA_DiagnoseList = DataContext.SelectNodes("BA_Diagnose");
                #endregion

                /*ErrorStrDictionary 错误字符释义字典 在这里生成*/
                #region--生成错误释义字典
                foreach (XmlNode n in BA_Fpage_Node)
                {
                    ErrorStrDictionary.BA_FPageDic.Clear();
                    ErrorStrDictionary.BA_FPageDic.Add(n.Name, n.Attributes["Key"].Value);
                }
                foreach (XmlNode n in BA_CastList[0])
                {
                    ErrorStrDictionary.BA_InvoiceDic.Clear();
                    ErrorStrDictionary.BA_InvoiceDic.Add(n.Name, n.Attributes["Key"].Value);
                }
                foreach (XmlNode n in BA_OperationList[0])
                {
                    ErrorStrDictionary.BA_OperationDic.Clear();
                    ErrorStrDictionary.BA_OperationDic.Add(n.Name, n.Attributes["Key"].Value);
                }
                foreach (XmlNode n in BA_DiagnoseList[0])
                {
                    ErrorStrDictionary.BA_DiagnoseDic.Clear();
                    ErrorStrDictionary.BA_DiagnoseDic.Add(n.Name, n.Attributes["Key"].Value);
                }
                #endregion

                /*数据校验 判空 值域 逻辑*/
                #region--判空校验
                List<String> NeedCheckNullParam = new List<string>() {"FP0",
                                                                    "FP3",
                                                                    "FP4",
                                                                    "FP5",
                                                                    "FP6",
                                                                    "FP6_Name",
                                                                    "FP8",
                                                                    "FP9",
                                                                    "FP9_Name",
                                                                    "FP14",
                                                                    "FP15",
                                                                    "FP17_YS",
                                                                    "FP22",
                                                                    "FP22_1",
                                                                    "FP23_NAME",
                                                                    "FP25",
                                                                    "FP27",
                                                                    "FP29_NAME",
                                                                    "FP31",
                                                                    "FP36_NAME",
                                                                    "FP37",
                                                                    "FP37_NAME",
                                                                    "FP52",
                                                                    "FP52_NAME",
                                                                    "FP55",
                                                                    "FP55_NAME",
                                                                    "FP80",
                                                                    "FP82",
                                                                    "FP83",
                                                                    "FP84",
                                                                    "FP85",
                                                                    "FP87",
                                                                    "FP91",
                                                                    "FP93",
                                                                    "FP94",
                                                                    "FP95",
                                                                    "FP95_1",
                                                                    "FP96",
                                                                    "FP116",
                                                                    "FP117",
                                                                    "FP118",
                                                                    "FP118_KZR",
                                                                    "FP118_ZRYS",
                                                                    "FP118_ZZYS",
                                                                    "FP122",
                                                                    "FP130",
                                                                    "FP130_YS",
                                                                    "FP136",
                                                                    "FP137_YS",
                                                                    "FP143",
                                                                    "FP143_Name",
                                                                    "FP148",
                                                                    "FP149",
                                                                    "FP151",
                                                                    "FP152",
                                                                    "FP153",
                                                                    "FP154",
                                                                    "FP155",
                                                                    "FP156",
                                                                    "Nationality_YS",
                                                                    "FP_YBLX",
                                                                    "FP_PatientID" };
                foreach (String str in NeedCheckNullParam)
                {
                    CheckNullParam(str, BA_Fpage_Node, errs);
                }
                #endregion

                #region--值域校验
                //1-2
                List<int> list_1_2 = new List<int> { 1, 2 };
                List<String> NeedCheckRangeParam_1_2 = new List<string>() {
                "FP95_1",
                "FP96",
                "FP143",
                "FP151",
                "FP152",
                "FP153",
                "FP154",
                "FP155",
                "FP156"};
                foreach (String str in NeedCheckRangeParam_1_2)
                {
                    CheckRangeParam(str, BA_Fpage_Node, errs, list_1_2);
                }

                //0-4
                List<int> list_0_4 = new List<int> { 0, 1, 2, 3, 4 };
                CheckRangeParam("FP148", BA_Fpage_Node, errs, list_0_4);

                //1-3
                List<int> list_1_3 = new List<int> { 1, 2, 3 };
                List<String> NeedCheckRangeParam_1_3 = new List<string>() {
                "FP122",
                "FP80",
                "FP82",
                "FP27",
                "FP3" };
                foreach (String str in NeedCheckRangeParam_1_3)
                {
                    CheckRangeParam(str, BA_Fpage_Node, errs, list_1_3);
                }

                //1-6
                List<int> list_1_6 = new List<int> { 1, 2, 3, 4, 5, 6 };
                CheckRangeParam("FP93", BA_Fpage_Node, errs, list_1_6);

                //1-4
                List<int> list_1_4 = new List<int> { 1, 2, 3, 4 };
                List<String> NeedCheckRangeParam_1_4 = new List<string>() {
                "FP91",
                "FP87"};
                foreach (String str in NeedCheckRangeParam_1_4)
                {
                    CheckRangeParam(str, BA_Fpage_Node, errs, list_1_4);
                }

                //0-3
                List<int> list_0_3 = new List<int> { 0, 1, 2, 3 };
                List<String> NeedCheckRangeParam_0_3 = new List<string>() {
                "FP85",
                "FP84",
                "FP83" };
                foreach (String str in NeedCheckRangeParam_0_3)
                {
                    CheckRangeParam(str, BA_Fpage_Node, errs, list_0_3);
                }

                //1-4and9
                List<int> list_1_4and9 = new List<int> { 1, 2, 3, 4, 9 };
                CheckRangeParam("FP8", BA_Fpage_Node, errs, list_1_4and9);

                //（GB/T2261.4）11\13\17\21\24\27\31\37\51\54\70\80\90
                List<int> list_11_90 = new List<int> { 11, 13, 17, 21, 24, 27, 31, 37, 51, 54, 70, 80, 90 };
                CheckRangeParam("FP9", BA_Fpage_Node, errs, list_11_90);

                //1-9
                List<int> list_1_9 = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
                CheckRangeParam("FP6", BA_Fpage_Node, errs, list_1_9);
                #endregion

                #region--逻辑校验
                //国籍为中国，民族不能为空
                if (BA_Fpage_Node.SelectSingleNode("Nationality_YS").InnerText.Trim() == "中国")
                {
                    //民族代码
                    if (BA_Fpage_Node.SelectSingleNode("FP11").InnerText.Trim() == "")
                    {
                        errs.Add(new Err(BA_Fpage_Node.SelectSingleNode("FP11").Attributes["Key"].Value, "国籍为中国的时候，民族代码不能为空"));
                    }
                    //民族名称
                    if (BA_Fpage_Node.SelectSingleNode("FP11_Name").InnerText.Trim() == "")
                    {
                        errs.Add(new Err(BA_Fpage_Node.SelectSingleNode("FP11_Name").Attributes["Key"].Value, "国籍为中国的时候，民族名称不能为空"));
                    }
                }
                //当随诊为1即是，随诊期限，随诊日期，必须填写
                if (BA_Fpage_Node.SelectSingleNode("FP96").InnerText.Trim() == "1")
                {
                    //随诊期限
                    if (BA_Fpage_Node.SelectSingleNode("FP97").InnerText.Trim() == "")
                    {
                        errs.Add(new Err(BA_Fpage_Node.SelectSingleNode("FP97").Attributes["Key"].Value, "当随诊为1，随诊期限必须填写"));
                    }
                    //随诊日期
                    if (BA_Fpage_Node.SelectSingleNode("FP97_Date").InnerText.Trim() == "")
                    {
                        errs.Add(new Err(BA_Fpage_Node.SelectSingleNode("FP97_Date").Attributes["Key"].Value, "当随诊为1，随诊日期必须填写"));
                    }
                }
                //此人过敏，必须填写过敏药物名称
                if (BA_Fpage_Node.SelectSingleNode("FP130").InnerText.Trim() == "2")
                {
                    //过敏药物
                    if (BA_Fpage_Node.SelectSingleNode("FP130_YS").InnerText.Trim() == "")
                    {
                        errs.Add(new Err(BA_Fpage_Node.SelectSingleNode("FP130_YS").Attributes["Key"].Value, "此人药物过敏，必须填写过敏药物名称"));
                    }
                }
                //金额判断
                foreach (XmlNode BA_CastNode in BA_CastList)
                {
                    List<String> costParamList = new List<String>() {
                    "F1",
                    "F2",
                    "F3",
                    "F4",
                    "F5",
                    "F6",
                    "F7",
                    "F8",
                    "F9",
                    "F10",
                    "F11",
                    "F12",
                    "F13",
                    "F14",
                    "F15",
                    "F16",
                    "F17",
                    "F18",
                    "F19",
                    "F20",
                    "F21",
                    "F22",
                    "F23",
                    "F24"
                    };
                    double count = 0;
                    foreach (String str in costParamList)
                    {
                        //费用项目对应的金额
                        string temp = BA_CastNode.SelectSingleNode(str).InnerText.Trim();
                        if (temp is double)
                        {
                            count += Convert.ToDouble(temp);
                        }
                    }
                    if (Convert.ToDouble(BA_CastNode.SelectSingleNode("TotMoney").InnerText.Trim()) != count)
                    {
                        errs.Add(new Err(BA_CastNode.SelectSingleNode("TotMoney").Attributes["Key"].Value, "金额信息错误，费用总额不等于其他费用之和"));
                    }
                }
                //所有表的ZYNum都需要相同 ：在下方循环处理字符串的时候处理
                #endregion

                #region--类型校验
                CheckDateTime("FP4", BA_Fpage_Node, errs);
                CheckDateTime("FP40", BA_Fpage_Node, errs);
                CheckDateTime("FP125", BA_Fpage_Node, errs);
                CheckDateTime("FP97_Date", BA_Fpage_Node, errs, "NULL");
                CheckDateTime("FP150", BA_Fpage_Node, errs, "NULL");
                #endregion

                /*病案 xml处理 删除所以的附加属性 赋值给全局变量（才能正常的反序列化为一个实体对象）*/
                #region--xml加工处理
                //所有表的ZYNum都需要相同
                String ZYCode = BA_Fpage_Node.SelectSingleNode("FP0").InnerText.Trim();
                foreach (XmlNode n in BA_Fpage_Node.ChildNodes)
                {
                    XmlElement ele = (XmlElement)n;
                    ele.RemoveAttribute("Key");
                }
                log.Info("首页_病案号（曼茶罗叫病案号其实是我们的住院号）:" + ZYCode);
                fpage = MyTools.XmlDeserialize<BA_FPage>(BA_Fpage_Node);

                /*手术 xml处理*/
                foreach (XmlNode BA_Operation_Node in BA_OperationList)
                {
                    if (BA_Operation_Node.SelectSingleNode("ZYNum").InnerText.Trim() != ZYCode)
                    {
                        throw new Exception("多项数据的“住院号”不是同一个");
                    }
                    foreach (XmlNode n in BA_Operation_Node.ChildNodes)
                    {
                        XmlElement ele = (XmlElement)n;
                        ele.RemoveAttribute("Key");
                    }
                    log.Info("手术表_手术代码:" + BA_Operation_Node.SelectSingleNode("OperationCode").InnerText.Trim());
                    C_BA_Operation c_BA_Operation = MyTools.XmlDeserialize<C_BA_Operation>(BA_Operation_Node);
                    //为临时表插入操作标志
                    c_BA_Operation.UserID = UserIDTemp;
                    operations.Add(c_BA_Operation);
                }

                /*诊断 xml处理*/
                foreach (XmlNode BA_Diagnose_Node in BA_DiagnoseList)
                {
                    if (BA_Diagnose_Node.SelectSingleNode("ZYNum").InnerText.Trim() != ZYCode)
                    {
                        throw new Exception("多项数据的“住院号”不是同一个");
                    }
                    foreach (XmlNode n in BA_Diagnose_Node.ChildNodes)
                    {
                        XmlElement ele = (XmlElement)n;
                        ele.RemoveAttribute("Key");
                    }
                    log.Info("诊断表_诊断编码:" + BA_Diagnose_Node.SelectSingleNode("DiagnoseCode").InnerText.Trim());
                    C_BA_Diagnose c_BA_Diagnose = MyTools.XmlDeserialize<C_BA_Diagnose>(BA_Diagnose_Node);
                    //为临时表插入操作标志
                    c_BA_Diagnose.UserID = UserIDTemp;
                    diagnoses.Add(c_BA_Diagnose);
                }

                /*金额 xml处理*/
                foreach (XmlNode BA_Cast_Node in BA_CastList)
                {
                    if (BA_Cast_Node.SelectSingleNode("ZYNum").InnerText.Trim() != ZYCode)
                    {
                        throw new Exception("多项数据的“住院号”不是同一个");
                    }
                    foreach (XmlNode n in BA_Cast_Node.ChildNodes)
                    {
                        XmlElement ele = (XmlElement)n;
                        ele.RemoveAttribute("Key");
                    }
                    log.Info("费用表_住院号:" + BA_Cast_Node.SelectSingleNode("ZYNum").InnerText.Trim());
                    invoices.Add(MyTools.XmlDeserialize<BA_Invoice>(BA_Cast_Node));
                }
                #endregion
            }
            catch (JsonReaderException e)//转为实体对象 发生异常捕获 数据类型错误
            {
                Err err = new Err();
                //错误信息Example:Unexpected character encountered while parsing value: [. Path 'FP8', line 1, position 130
                String errStr = e.Message;
                //根据“'”号分割字符串，并且取第二个作为param
                String param = errStr.Split(new char[1] { '\'' })[1];
                errs.Add(new Err(param, errStr));
                log.Error("xml解析失败,原因如下\r\n" + e.ToString() + LogLine);
            }
            catch (Exception e)//未预料到的异常
            {
                Err err = new Err();
                String errStr = e.ToString();
                String title = "未预料到的异常，请联系管理员";
                err.Res = errStr;
                err.Key = title;
                errs.Add(new Err(title, errStr));
                log.Error("未预料到的异常,原因如下\r\n" + e.ToString() + LogLine);
            }
            #endregion

            #region>>保存数据
            //查询此人是否已经存在 不存在不允许调用
            String ZYNum = fpage.FP0.Trim();
            var PatientNum = db.BA_FPage.Where(tb => tb.FP0 == ZYNum).Count();

            if (PatientNum == 0)
            {
                errs.Add(new Err("此病人不存在", "根据查询，此病人不存在，请检查病案号"));
            }

            //解析有错则跳出，解析无错才保存
            if (errs.Count > 1)
            {
                return ErrInfoToStr(errs);
            }

            /*解析无错继续执行*/

            //诊断和手术保存
            try
            {
                //诊断至少需要填写一条
                int diagnoseCount = 0;
                foreach (C_BA_Diagnose diagnose in diagnoses)
                {
                    if (diagnose.DiagnoseCode.Trim() != "")//如果诊断代码不为空
                    {
                        db.C_BA_Diagnose.Add(diagnose);
                        diagnoseCount++;
                    }
                }
                //判断有没有插入诊断
                if (diagnoseCount < 1)
                {
                    errs.Add(new Err("数据错误", "至少需要插入一条诊断"));
                }

                //插入手术信息
                foreach (C_BA_Operation operation in operations)
                {
                    if (operation.OperationCode.Trim() != "")
                    {
                        db.C_BA_Operation.Add(operation);
                    }
                }
                db.SaveChanges();
            }
            catch (DbEntityValidationException dbErr)//字段错误列表
            {
                ParamExceptionRead(errs, dbErr);
            }
            catch (Exception e)
            {
                errs.Add(new Err("保存失败", e.Message));
                log.Error("保存失败,原因如下\r\n" + e.ToString() + LogLine);
            }

            //解析有错则跳出，解析无错才继续保存
            if (errs.Count > 1)
            {
                return ErrInfoToStr(errs);
            }

            //调用存储过程，开启事务
            var transction = db.Database.BeginTransaction();
            try
            {
                //插入金额信息(同样需要放在实务中处理，所以干脆和调用存储过程放在一起处理)
                foreach (BA_Invoice invoice in invoices)
                {
                    BA_Invoice findInvoice = db.BA_Invoice.Where(I => I.ZYNum == invoice.ZYNum).FirstOrDefault();
                    if (findInvoice != null)
                    {
                        findInvoice = invoice;
                    }
                    else
                    {
                        db.BA_Invoice.Add(invoice);
                    }
                }

                #region>>执行BA_FPageSave存储过程
                int FPageSaveBack = db.BA_FPageSave(fpage.FP0,
                                fpage.FP1,
                                fpage.FP3,
                                fpage.FP4,
                                fpage.FP5,
                                fpage.FP6,
                                fpage.FP6_Name,
                                fpage.FP8,
                                fpage.FP9,
                                fpage.FP9_Name,
                                fpage.FP9_YS,
                                fpage.FP10,
                                fpage.FP10_Name,
                                fpage.FP10_YS,
                                fpage.FP11,
                                fpage.FP11_Name,
                                fpage.FP11_YS,
                                fpage.Nationality_YS,
                                fpage.PersonNo,
                                fpage.FP12,
                                fpage.FP14,
                                fpage.FP14_PostCode,
                                fpage.FP15,
                                fpage.FP17,
                                fpage.FP17_Name,
                                fpage.FP17_YS,
                                fpage.FP14_PostCode,
                                fpage.FP22,
                                fpage.FP22_1,
                                fpage.FP22_2,
                                fpage.FP22_3,
                                fpage.FP24,
                                fpage.FP27,
                                fpage.FP30,
                                fpage.FP36_YS,
                                fpage.FP36,
                                fpage.FP36_NAME,
                                fpage.FP36_YSName,
                                fpage.FP37_YS,
                                fpage.FP37,
                                fpage.FP37_NAME,
                                fpage.FP40,
                                fpage.FP53_YS,
                                fpage.FP53,
                                fpage.FP53_NAME,
                                fpage.FP54,
                                fpage.FP55_YS,
                                fpage.FP69,
                                fpage.FP70,
                                fpage.FP71,
                                fpage.FP72,
                                fpage.FP73,
                                fpage.FP74,
                                fpage.FP75,
                                fpage.FP76,
                                fpage.FP76_1,
                                fpage.FP77,
                                fpage.FP80,
                                fpage.FP81,
                                fpage.FP82,
                                fpage.FP83,
                                fpage.FP84,
                                fpage.FP85,
                                fpage.FP86,
                                fpage.FP87,
                                fpage.FP90,
                                fpage.FP91,
                                fpage.FP93,
                                fpage.FP94,
                                fpage.FP95,
                                fpage.FP96,
                                fpage.FP97,
                                fpage.FP97_Date,
                                fpage.FP98,
                                fpage.FP114,
                                fpage.FP115,
                                fpage.FP116,
                                fpage.FP117,
                                fpage.FP118,
                                fpage.FP118_KZR,
                                fpage.FP118_ZRYS,
                                fpage.FP118_ZZYS,
                                fpage.FP120,
                                fpage.FP122,
                                fpage.FP125,
                                fpage.Note,
                                //此号码为插入唯一标识
                                UserIDTemp,
                                fpage.FP125_OperName,
                                fpage.FP129,
                                fpage.FP129_Name,
                                fpage.FP129_YS,
                                fpage.FP130_YS,
                                fpage.FP130,
                                fpage.FP134,
                                fpage.FP135,
                                fpage.FP136,
                                fpage.FP137,
                                fpage.FP137_Name,
                                fpage.FP137_YS,
                                fpage.FP138,
                                fpage.FP139,
                                fpage.FP140,
                                fpage.FP140_Name,
                                fpage.FP141,
                                fpage.FP142,
                                fpage.FP142_Name,
                                fpage.FP143,
                                fpage.FP143_Name,
                                fpage.FP144_D,
                                fpage.FP144_H,
                                fpage.FP144_M,
                                fpage.FP145_D,
                                fpage.FP145_H,
                                fpage.FP145_M,
                                fpage.FP146,
                                fpage.FP146_Day,
                                fpage.FP147,
                                fpage.FP148,
                                fpage.FP149,
                                fpage.FP150,
                                null,//fpage.VER
                                null,
                                fpage.FP95_1,
                                fpage.FP146_1,
                                fpage.FP146_2,
                                fpage.FP146_3,
                                fpage.FP146_4,
                                fpage.FP148_1,
                                fpage.FP151,
                                fpage.FP151_1,
                                fpage.FP151_2,
                                fpage.FP152,
                                fpage.FP152_1,
                                fpage.FP152_2,
                                fpage.FP153,
                                fpage.FP153_1,
                                fpage.FP154,
                                fpage.FP154_1,
                                fpage.FP155,
                                fpage.FP155_1,
                                fpage.FP155_2,
                                fpage.FP156,
                                fpage.FP156_1,
                                fpage.FP156_2,
                                fpage.FP157,
                                fpage.FP157_1,
                                fpage.FP157_2,
                                fpage.FP157_3,
                                fpage.FP157_4,
                                fpage.FP158,
                                fpage.FP158_1,
                                fpage.FP158_2,
                                fpage.FP158_3,
                                fpage.FP159,
                                fpage.FP160,
                                fpage.FP_YBLX);
                #endregion
                log.Info("FPageSave存储过程返回:" + FPageSaveBack.ToString());
                if (FPageSaveBack == -1)
                {
                    throw new Exception("此病案已由病案室审核");
                }
                else if (FPageSaveBack == -2)
                {
                    throw new Exception("此病案已由科室医师审核");
                }

                if (FPageSaveBack == 0)
                {
                    db.SaveChanges();
                    transction.Commit();
                }
            }
            catch (DbUpdateException updateErr)//插入重复数据
            {
                errs.Add(new Err("保存失败", "插入重复值"));
                log.Error("保存失败,原因如下\r\n" + updateErr.ToString() + LogLine);
                transction.Rollback();
            }
            catch (DbEntityValidationException dbErr)//字段错误列表
            {
                ParamExceptionRead(errs, dbErr);
                transction.Rollback();
            }
            catch (Exception e)
            {
                errs.Add(new Err("保存失败", e.Message));
                log.Error("保存失败,原因如下\r\n" + e.ToString() + LogLine);
                transction.Rollback();
            }
            finally
            {
                transction.Dispose();
            }
            #endregion

            string res = ErrInfoToStr(errs);
            log.Info(LogLine);
            return res;
        }

        /// <summary>
        /// 取消入院 操作码5
        /// </summary>
        /// <param name="xml"></param>
        /// <returns></returns>
        [WebMethod(Description = "对HIS：取消入院接口")]
        public string CancelInHosp(String xml)
        {
            log.Info(LogLine + "取消入院接口ing");
            log.Debug(LogLine + xml + LogLine);
            List<Err> errs = new List<Err>();
            try
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.LoadXml(xml);
                XmlNode root = xmlDoc.DocumentElement;
                XmlNode Body = root.SelectSingleNode("Body");
                XmlNode DataContext = Body.SelectSingleNode("InpatientEncounterCancelRt");
                //
                HisRequest req = new HisRequest();
                //时间拼接 采用对方更新时间
                String OperDateStr = DataContext.SelectSingleNode("UpdateDate").InnerText.Trim() + " " + DataContext.SelectSingleNode("UpdateTime").InnerText.Trim();
                //住院号
                req.ZYNum = DataContext.SelectSingleNode("PAADMVisitNumber").InnerText.Trim();
                //操作员代码
                req.OperCode = DataContext.SelectSingleNode("UpdateUserCode").InnerText.Trim();
                //操作员姓名
                req.OperName = DataContext.SelectSingleNode("UpdateUserDesc").InnerText.Trim();
                //出科时间
                req.CkDate = Convert.ToDateTime(OperDateStr);
                //5表示取消入院操作
                req.ReqFlag = 5;
                //以下数据
                //入院接口处已经存入数据库，从数据库中查询得到
                BA_FPage b = db.BA_FPage.Where(x => x.FP0 == req.ZYNum).FirstOrDefault();
                if (b == null)
                {
                    errs.Add(new Err("此人不存在", "检查此人是否已经入院"));
                }
                else
                {
                    //患者姓名
                    req.PatientName = b.FP2;
                    //入院科室代码
                    req.KSCode = b.FP23;
                    //入院床号
                    req.BedCode = b.FP24;
                    ProcForHisReq(errs, req);
                }
            }
            catch (NullReferenceException e)//xml节点缺少
            {
                Err err = new Err();
                String errStr = "请检查必须传入的xml节点 ps:" + e.Message;
                String title = "所需xml节点缺失";
                err.Res = errStr;
                err.Key = title;
                errs.Add(new Err(title, errStr));
                log.Error("所需xml节点缺失\r\n" + e.ToString() + LogLine);
            }
            catch (Exception e)//未预料到的异常
            {
                Err err = new Err();
                String errStr = e.Message;
                String title = "未预料到的异常";
                err.Res = errStr;
                err.Key = title;
                errs.Add(new Err(title, errStr));
                log.Error("未预料到的异常,原因如下\r\n" + e.ToString() + LogLine);
            }
            return ErrInfoToStr(errs);
        }

        /// <summary>
        /// 取消出院 操作码3
        /// </summary>
        /// <param name="xml"></param>
        /// <returns></returns>
        [WebMethod(Description = "对HIS：取消出院接口")]
        public string CancelOutHosp(String xml)
        {
            log.Info(LogLine + "取消出院接口ing");
            log.Debug(LogLine + xml + LogLine);
            List<Err> errs = new List<Err>();
            try
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.LoadXml(xml);
                XmlNode root = xmlDoc.DocumentElement;
                XmlNode Body = root.SelectSingleNode("Body");
                XmlNode DataContext = Body.SelectSingleNode("InpatientDischargeCancelRt");
                //
                HisRequest req = new HisRequest();
                //使用对方更新时间
                String OperDateStr = DataContext.SelectSingleNode("UpdateDate").InnerText.Trim() + " "
                    + DataContext.SelectSingleNode("UpdateTime").InnerText.Trim();
                //住院号
                req.ZYNum = DataContext.SelectSingleNode("PAADMVisitNumber").InnerText.Trim();
                //操作员代码
                req.OperCode = DataContext.SelectSingleNode("UpdateUserCode").InnerText.Trim();
                //操作员name
                req.OperName = DataContext.SelectSingleNode("UpdateUserDesc").InnerText.Trim();
                //入科时间
                req.RkDate = Convert.ToDateTime(OperDateStr);
                //3 表示取消出院操作
                req.ReqFlag = 3;
                //以下数据出院处已经存入数据库，从数据库中查询
                BA_FPage b = db.BA_FPage.Where(x => x.FP0 == req.ZYNum).FirstOrDefault();
                if (b == null)
                {
                    errs.Add(new Err("此人不存在", "检查此人是否已经出院"));
                }
                else
                {
                    //患者姓名
                    req.PatientName = b.FP2;
                    //出院科室code
                    req.KSCode = b.FP29;
                    //出院床号
                    req.BedCode = b.FP30;
                    ProcForHisReq(errs, req);
                }
            }
            catch (NullReferenceException e)//xml节点缺少
            {
                Err err = new Err();
                String errStr = "请检查必须传入的xml节点 ps:" + e.Message;
                String title = "所需xml节点缺失";
                err.Res = errStr;
                err.Key = title;
                errs.Add(new Err(title, errStr));
                log.Error("所需xml节点缺失\r\n" + e.ToString() + LogLine);
            }
            catch (Exception e)//未预料到的异常
            {
                Err err = new Err();
                String errStr = e.Message;
                String title = "未预料到的异常";
                err.Res = errStr;
                err.Key = title;
                errs.Add(new Err(title, errStr));
                log.Error("未预料到的异常,原因如下\r\n" + e.ToString() + LogLine);
            }
            return ErrInfoToStr(errs);
        }

        /// <summary>
        /// 转科 操作码2
        /// </summary>
        /// <param name="xml"></param>
        /// <returns></returns>
        [WebMethod(Description = "对HIS：转科接口")]
        public string ChangeKS(String xml)
        {
            log.Info(LogLine + "转科接口ing");
            log.Debug(LogLine + xml + LogLine);
            List<Err> errs = new List<Err>();
            try
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.LoadXml(xml);
                XmlNode root = xmlDoc.DocumentElement;
                XmlNode Body = root.SelectSingleNode("Body");
                XmlNode DataContext = Body.SelectSingleNode("AdmTransactionRt");
                //
                HisRequest req = new HisRequest();
                //取的是对方转入时间
                String OperDateStr = DataContext.SelectSingleNode("PAADMTEndDate").InnerText.Trim() + " "
                    + DataContext.SelectSingleNode("PAADMTEndTime").InnerText.Trim();
                req.ZYNum = DataContext.SelectSingleNode("PAADMVisitNumber").InnerText.Trim();
                //操作员code
                req.OperCode = DataContext.SelectSingleNode("UpdateUserCode").InnerText.Trim();
                //操作员name
                req.OperName = DataContext.SelectSingleNode("UpdateUserDesc").InnerText.Trim();
                //转科时间
                req.ZkDate = Convert.ToDateTime(OperDateStr);
                //2 表示转科
                req.ReqFlag = 2;
                BA_FPage b = db.BA_FPage.Where(x => x.FP0 == req.ZYNum).FirstOrDefault();
                if (b == null)
                {
                    errs.Add(new Err("此人不存在", "检查此人是否存在"));
                }
                else
                {
                    //患者姓名
                    req.PatientName = b.FP2;
                    //转入科室代码
                    req.KSCode = DataContext.SelectSingleNode("PAADMTTargDeptCode").InnerText.Trim();
                    //转出床号
                    req.BedCode = DataContext.SelectSingleNode("PAADMTOrigBedCode").InnerText.Trim();
                    ProcForHisReq(errs, req);
                }
            }
            catch (NullReferenceException e)//xml节点缺少
            {
                Err err = new Err();
                String errStr = "请检查必须传入的xml节点 ps:" + e.Message;
                String title = "所需xml节点缺失";
                err.Res = errStr;
                err.Key = title;
                errs.Add(new Err(title, errStr));
                log.Error("所需xml节点缺失\r\n" + e.ToString() + LogLine);
            }
            catch (Exception e)//未预料到的异常
            {
                Err err = new Err();
                String errStr = e.Message;
                String title = "未预料到的异常";
                err.Res = errStr;
                err.Key = title;
                errs.Add(new Err(title, errStr));
                log.Error("未预料到的异常,原因如下\r\n" + e.ToString() + LogLine);
            }
            return ErrInfoToStr(errs);
        }

        /// <summary>
        /// 入院 操作码1
        /// </summary>
        /// <param name="xml"></param>
        /// <returns></returns>
        [WebMethod(Description = "对HIS：入院接口")]
        public string InHosp(String xml)
        {
            log.Info(LogLine + "入院接口接口ing");
            log.Debug(LogLine + xml + LogLine);
            List<Err> errs = new List<Err>();

            //为捕获xml字段缺失异常
            try
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.LoadXml(xml);
                XmlNode root = xmlDoc.DocumentElement;
                XmlNode Body = root.SelectSingleNode("Body");
                XmlNode DataContext = Body.SelectSingleNode("InpatientEncounterStartedRt");
                //变量
                HisRequest req = new HisRequest();
                //时间拼接 采用对方入科时间
                String OperDateStr = DataContext.SelectSingleNode("PAADMStartDate").InnerText.Trim() + " "
                    + DataContext.SelectSingleNode("PAADMStartTime").InnerText.Trim();
                //住院号
                req.ZYNum = DataContext.SelectSingleNode("PAADMVisitNumber").InnerText.Trim();
                //病人姓名
                req.PatientName = DataContext.SelectSingleNode("PATName").InnerText.Trim();
                //入院科室代码
                req.KSCode = DataContext.SelectSingleNode("PAADMAdmDeptCode").InnerText.Trim();

                //TODO 入院床号等待对方给出字段
                String BedCodeTemp = "";
                try
                {
                    BedCodeTemp = DataContext.SelectSingleNode("PAADMCurBedNo").InnerText.Trim();
                }
                catch
                {
                    BedCodeTemp = "";
                }
                req.BedCode = BedCodeTemp;
                //操作员Code
                req.OperCode = DataContext.SelectSingleNode("UpdateUserCode").InnerText.Trim();
                //操作员Name
                req.OperName = DataContext.SelectSingleNode("UpdateUserDesc").InnerText.Trim();
                //入科时间
                req.RkDate = Convert.ToDateTime(OperDateStr);
                //1表示入院操作
                req.ReqFlag = 1;
                //医师代码（仅入院需要）
                req.YSCode = DataContext.SelectSingleNode("PAADMAdmitDocCode").InnerText.Trim();
                ProcForHisReq(errs, req);
            }
            catch (NullReferenceException e)//xml节点缺少
            {
                Err err = new Err();
                String errStr = "请检查必须传入的xml节点 ps:" + e.Message;
                String title = "所需xml节点缺失";
                err.Res = errStr;
                err.Key = title;
                errs.Add(new Err(title, errStr));
                log.Error("所需xml节点缺失\r\n" + e.ToString() + LogLine);
            }
            catch (Exception e) //未预料到的异常
            {
                Err err = new Err();
                String errStr = e.Message;
                String title = "未预料到的异常";
                err.Res = errStr;
                err.Key = title;
                errs.Add(new Err(title, errStr));
                log.Error("未预料到的异常,原因如下\r\n" + e.ToString() + LogLine);
            }
            return ErrInfoToStr(errs);
        }

        /// <summary>
        /// 出院 操作码4
        /// </summary>
        /// <param name="xml"></param>
        /// <returns></returns>
        [WebMethod(Description = "对HIS：出院接口")]
        public string OutHosp(String xml)
        {
            log.Info(LogLine + "出院接口ing");
            log.Debug(LogLine + xml + LogLine);
            List<Err> errs = new List<Err>();
            try
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.LoadXml(xml);
                XmlNode root = xmlDoc.DocumentElement;
                XmlNode Body = root.SelectSingleNode("Body");
                XmlNode DataContext = Body.SelectSingleNode("InpatientDischargeRt");
                //
                HisRequest req = new HisRequest();
                //时间拼接，出院时间取对方出院时间
                String OperDateStr = DataContext.SelectSingleNode("PAADMEndDate").InnerText.Trim() + " "
                    + DataContext.SelectSingleNode("PAADMEndTime").InnerText.Trim();
                //住院号
                req.ZYNum = DataContext.SelectSingleNode("PAADMVisitNumber").InnerText.Trim();
                //操作员代码
                req.OperCode = DataContext.SelectSingleNode("UpdateUserCode").InnerText.Trim();
                //操作员name
                req.OperName = DataContext.SelectSingleNode("UpdateUserDesc").InnerText.Trim();
                //出科时间
                req.CkDate = Convert.ToDateTime(OperDateStr);
                //4 表示出院操作
                req.ReqFlag = 4;
                //出院是否死亡，根据对方工程师告知，出院状态5 表示死亡
                req.DeathFlag = DataContext.SelectSingleNode("PAADMDisStatusCode").InnerText.Trim() == "5" ? 1 : 0;
                //病人姓名
                req.PatientName = DataContext.SelectSingleNode("PATName").InnerText.Trim();
                //出院科室代码
                req.KSCode = DataContext.SelectSingleNode("PAADMDisDeptCode").InnerText.Trim();

                //TODO 出院床号等待对方给出字段
                String BedCodeTemp = "";
                try
                {
                    BedCodeTemp = DataContext.SelectSingleNode("PAADMCurBedNo").InnerText.Trim();
                }
                catch
                {
                    BedCodeTemp = "";
                }
                req.BedCode = BedCodeTemp;
                ProcForHisReq(errs, req);
            }
            catch (NullReferenceException e)//xml节点缺少
            {
                Err err = new Err();
                String errStr = "请检查必须传入的xml节点 ps:" + e.Message;
                String title = "所需xml节点缺失";
                err.Res = errStr;
                err.Key = title;
                errs.Add(new Err(title, errStr));
                log.Error("所需xml节点缺失\r\n" + e.ToString() + LogLine);
            }
            catch (Exception e)//未预料到的异常
            {
                Err err = new Err();
                String errStr = e.Message;
                String title = "未预料到的异常";
                err.Res = errStr;
                err.Key = title;
                errs.Add(new Err(title, errStr));
                log.Error("未预料到的异常,原因如下\r\n" + e.ToString() + LogLine);
            }
            return ErrInfoToStr(errs);
        }

        /***以下为，工具方法*********************************************************************************************************/

        /// <summary>
        /// 参数判空-针对曼荼罗的数据判断-虽然只有一次引用但是是在循环中使用的
        /// </summary>
        /// <param name="str">需要判断的字段</param>
        /// <param name="node">需要判断的xmlnode</param>
        /// <param name="errs">错误list</param>
        private void CheckNullParam(String str, XmlNode node, List<Err> errs)
        {
            Err er = new Err();
            try
            {
                if (node.SelectSingleNode(str).InnerText.Trim() == "")
                {
                    er.Key = node.SelectSingleNode(str).Attributes["Key"].Value;
                    er.Res = "此字段不能为空";
                    errs.Add(er);
                }
            }
            catch (NullReferenceException e)
            {
                er.Key = str;
                er.Res = str + "字段缺失 " + e.Message;
                errs.Add(er);
            }
        }

        /// <summary>
        /// 参数判断值域-针对曼荼罗的数据判断
        /// </summary>
        /// <param name="str">需要判断的字段</param>
        /// <param name="node">需要判断的xmlnode</param>
        /// <param name="errs">错误list</param>
        /// <param name="range">值域list</param>
        private void CheckRangeParam(String str, XmlNode node, List<Err> errs, List<int> range)
        {
            Err er = new Err();
            String rangeStr = "";
            foreach (int i in range)
            {
                rangeStr += i.ToString() + ",";
            }
            try
            {
                int param = Convert.ToInt32(node.SelectSingleNode(str).InnerText.Trim());
                if (!range.Contains(param))
                {
                    er.Key = node.SelectSingleNode(str).Attributes["Key"].Value;
                    er.Res = "此字段值域为" + rangeStr + "你填入的值不在此范围内";
                    errs.Add(er);
                }
            }
            catch (Exception e)
            {
                er.Key = str;
                er.Res = e.Message;
                errs.Add(er);
            }
        }

        private void CheckDateTime(String str, XmlNode node, List<Err> errs)
        {
            String dateStr = node.SelectSingleNode(str).InnerText.Trim();
            if (!DateTime.TryParse(dateStr, out DateTime dateTemp))
            {
                Err er = new Err
                {
                    Key = node.SelectSingleNode(str).Attributes["Key"].Value,
                    Res = "此字段为时间类型，传入类型不正确"
                };
                errs.Add(er);
            }
        }

        private void CheckDateTime(String str, XmlNode node, List<Err> errs, String nullFlag)
        {
            String dateStr = node.SelectSingleNode(str).InnerText.Trim();
            if (!dateStr.Equals(""))
            {
                if (!DateTime.TryParse(dateStr, out DateTime dateTemp))
                {
                    Err er = new Err
                    {
                        Key = node.SelectSingleNode(str).Attributes["Key"].Value,
                        Res = "此字段为时间类型，传入类型不正确"
                    };
                    errs.Add(er);
                }
            }
        }

        /// <summary>
        /// 根据错误list返回错误xml字符串
        /// </summary>
        /// <param name="errs"></param>
        /// <returns></returns>
        private String ErrInfoToStr(List<Err> errs)
        {
            String code = "";
            //XML解析工具
            XmlDocument xmlRes = new XmlDocument();
            XmlElement Response;//根目录
            XmlElement MessageHeader;//消息头
            XmlElement XMLCode;//状态码
            XmlElement XMLDesc;//信息块

            Response = xmlRes.CreateElement("", "Response", "");
            xmlRes.AppendChild(Response);

            MessageHeader = xmlRes.CreateElement("", "MessageHeader", "");
            Response.AppendChild(MessageHeader);

            XMLCode = xmlRes.CreateElement("", "Code", "");
            XMLDesc = xmlRes.CreateElement("", "Desc", "");

            if (errs.Count < 1)//如果解析成功则不需要传送Item
            {
                code = "0";
                XMLDesc.InnerText = "解析成功";
            }
            else
            {
                code = "1";
                foreach (Err e in errs)
                {
                    XmlElement XMLItem = xmlRes.CreateElement("", "Item", "");
                    XMLItem.SetAttribute("Key", e.Key);
                    XMLItem.SetAttribute("Error", e.Res);
                    XMLDesc.AppendChild(XMLItem);
                }
            }

            XMLCode.InnerText = code;
            Response.AppendChild(XMLCode);
            Response.AppendChild(XMLDesc);
            String res = MyTools.ConvertXmlToString(xmlRes);
            log.Info("返回信息如下" + "\n\r" + res);
            return res;
        }

        private KSCODE GetKSInfo(String Code)
        {
            //DH_KSCode
            var KsInfo = db.KSCODE.Where(r => r.DH_CODE == Code).FirstOrDefault<KSCODE>();
            return KsInfo;
        }

        /// <summary>
        /// HIS请求调用存储过程
        /// </summary>
        /// <param name="errs">错误列表</param>
        /// <param name="req">请求类</param>
        private void ProcForHisReq(List<Err> errs, HisRequest req)
        {
            log.Info("调用存储过程参数>>>>" + req.ToString());

            //数据库合理性判断
            //通用变量检查(必须有值)
            if ((req.ZYNum is null) || (req.ZYNum.Trim().Equals("")))
            {
                errs.Add(new Err("住院号", "住院号必须填写"));
                return;
            }
            if ((req.PatientName is null) || (req.PatientName.Trim().Equals("")))
            {
                errs.Add(new Err("病人姓名", "病人姓名必须填写"));
                return;
            }

            req.BedCode = (req.BedCode is null) ? "" : req.BedCode;

            if ((req.OperCode is null) || (req.OperCode.Trim().Equals("")))
            {
                errs.Add(new Err("操作员代码", "操作员代码必须填写"));
                return;
            }
            if ((req.OperName is null) || (req.OperName.Trim().Equals("")))
            {
                errs.Add(new Err("操作员姓名", "操作员姓名必须填写"));
                return;
            }
            //特异性检查(某个方法必须传的值)
            //入院出院特异检查
            int ReqFlag = req.ReqFlag;//操作标志
            KSCODE KsInfo = null;//科室信息对象
            if (ReqFlag == 1 || ReqFlag == 4 || ReqFlag == 2)
            {
                String KSCode = req.KSCode;//科室代码
                //条件判断
                if ((KSCode is null) || KSCode.Equals(""))
                {
                    errs.Add(new Err("科室编码", "需要传入科室代码"));
                    return;
                }
                else
                {
                    KsInfo = GetKSInfo(KSCode);
                }
                if (!(KsInfo is null))
                {
                    req.KSCode = KsInfo.CODE;//替换科室代码
                }
                else
                {
                    errs.Add(new Err("科室代码传入错误", "传入科室 与 病案科室 无对应关系"));
                    return;
                }
            }

            //if (ReqFlag == 1)
            //{
            //    if ((req.YSCode is null) || (req.YSCode.Trim().Equals("")))
            //    {
            //        errs.Add(new Err("医师编码", "入院接口，医师代码必须填写"));
            //        return;
            //    }
            //}

            //开启事务
            var transction = db.Database.BeginTransaction();

            try
            {
                var DeathFlag = req.DeathFlag;
                DeathFlag = (DeathFlag is null) ? 0 : DeathFlag;
                int ZYKSCWFPBack = db.ZYKSCWFP(
                    req.ZYNum.Trim(),           //string zynum,
                    req.PatientName.Trim(),     //string brname,
                    req.KSCode.Trim(),          //string kscode,
                    req.BedCode.Trim(),         //string cwname,
                    req.OperCode.Trim(),        //string opercode,
                    req.OperName.Trim(),        //string opername,
                    req.ReqFlag,                //Nullable<int> flag,
                    DeathFlag,                  //Nullable<int> swflag,
                    req.YSCode,                 //string yscode,
                    req.RkDate,                 //Nullable < System.DateTime > rkdate,
                    req.CkDate,                 //Nullable < System.DateTime > ckdate,
                    req.ZkDate,                 //Nullable < System.DateTime > zkdate,
                    null);                      //Nullable<decimal> keyno
                db.SaveChanges();
                log.Info("ZYKSCWFP存储过程返回：" + ZYKSCWFPBack.ToString());
                switch (ZYKSCWFPBack)
                {
                    case 101:
                        errs.Add(new Err("重复入院，该病人已入院", "数据错误"));
                        break;

                    case 201:
                        errs.Add(new Err("重复执行转科", "数据错误"));
                        break;

                    case 202:
                        errs.Add(new Err("不能进行转科，该病人已出院", "数据错误"));
                        break;

                    case 203:
                        errs.Add(new Err("每天只能进行一次转科", "数据错误"));
                        break;

                    case 301:
                        errs.Add(new Err("不能取消出院，医师已审核", "数据错误"));
                        break;

                    case 302:
                        errs.Add(new Err("不能取消出院，病案室已审核", "数据错误"));
                        break;

                    case 303:
                        errs.Add(new Err("不能取消出院，病人尚未出院", "数据错误"));
                        break;

                    case 401:
                        errs.Add(new Err("重复出院，该病人已出院", "数据错误"));
                        break;

                    case 402:
                        errs.Add(new Err("不能出院，该病人有转科申请", "数据错误"));
                        break;

                    case 403:
                        errs.Add(new Err("该病人在当前日期后由转科，不能进行出院操作", "数据错误"));
                        break;

                    case 404:
                        errs.Add(new Err("该病人已发生转科，且现在不在当前科室", "数据错误"));
                        break;

                    case 501:
                        errs.Add(new Err("当前患者未入院，不能取消入院", "数据错误"));
                        break;

                    case 502:
                        errs.Add(new Err("不能取消入院，该病人已发生转科", "数据错误"));
                        break;

                    case 503:
                        errs.Add(new Err("不能取消入院，该病人已申请转科", "数据错误"));
                        break;

                    case 504:
                        errs.Add(new Err("不能取消入院，该病人已出院", "数据错误"));
                        break;

                    case 601:
                        errs.Add(new Err("当前非最后一次转科，请先取消最后一次转科", "数据错误"));
                        break;

                    case 602:
                        errs.Add(new Err("当前患者已出院", "数据错误"));
                        break;

                    case -1:
                        errs.Add(new Err("操作失败", "数据库保存错误"));
                        log.Info("操作失败，数据库保存错误");
                        transction.Rollback();
                        break;

                    case 0:
                        transction.Commit();
                        log.Info("保存成功");
                        break;

                    default:
                        errs.Add(new Err("操作失败", "存储过程返回值为" + ZYKSCWFPBack.ToString()));
                        log.Info("预料之外的返回值");
                        break;
                }

                if (ZYKSCWFPBack != 0)
                {
                    transction.Rollback();
                }
            }
            catch (Exception e)
            {
                errs.Add(new Err("保存失败", e.Message));
                log.Error("保存失败\r\n" + e.ToString());
                transction.Rollback();
            }
            finally
            {
                transction.Dispose();
            }
        }

        /// <summary>
        /// 数据库参数错误解析
        /// </summary>
        /// <param name="errs">错误列表</param>
        /// <param name="dbErr">异常信息</param>
        private void ParamExceptionRead(List<Err> errs, DbEntityValidationException dbErr)
        {
            //解析数据库验证错误(就是字段约束等)
            foreach (var vErrList in dbErr.EntityValidationErrors)
            {
                foreach (var vErr in vErrList.ValidationErrors)
                {
                    String className = vErrList.Entry.Entity.GetType().FullName;
                    String paramName = vErr.PropertyName;
                    String errStr = vErr.ErrorMessage;
                    Err e = new Err();
                    className = className.Substring(className.LastIndexOf(".") + 1);
                    log.Error(
                        string.Format(
                        "类: {0}, 参数名: {1}, 错误信息: {2}",
                        className,
                        paramName,
                        errStr)
                        );
                    //判断能不能在错误字典中找到对应项目
                    if ((ErrorStrDictionary.Tables[className]).ContainsKey(paramName))
                    {
                        String keyStr = (ErrorStrDictionary.Tables[className])[paramName];
                        e = new Err(keyStr, errStr);
                    }
                    else
                    {
                        e = new Err(className + ":" + paramName, errStr);
                    }
                    errs.Add(e);
                }
            }
        }
    }
}